using System;
using System.Collections.Generic;

namespace SBPweb.Logging
{
    /// <summary>
    /// Flag enumeration to help composing <see cref="LogManager.FallbackSeverityFilter"> and category severity filters.</see>.
    /// </summary>
    /// <example>
    /// The following example shows how to initialize logging with default structure gathered from configuration and
    /// how to filter out messages with different severities.
    /// <code>
    /// private void MainForm_Load(object sender, EventArgs e)
    /// {
    ///     LogManager.Initialize();
    ///     
    ///     // Only messages with Critical and Error severity will be written
    ///     LogManager.SeverityFilter["NetworkListeners"] = SeverityLevel.Information | SeverityLevel.Warning | SeverityLevel.Verbose;
    /// }
    /// </code>
    /// </example>
    [Flags]
    public enum SeverityLevel
    {
        /// <summary>
        /// Auxilliary flag
        /// </summary>
        None = 0,
        /// <summary>
        /// Fatal error or application crash.
        /// </summary>
        Critical = 1,
        /// <summary>
        /// Recoverable error.
        /// </summary>
        Error = 2,
        /// <summary>
        /// Noncritical problem.
        /// </summary>
        Warning = 4,
        /// <summary>
        /// Informational message.
        /// </summary>
        Information = 8,
        /// <summary>
        /// Debugging trace.
        /// </summary>
        Verbose = 16
    }

    /// <summary>
    /// Logger entry point. Initializes and Terminates custom resources and the logger subsystem.
    /// </summary>
    public static partial class LogManager
    {
        private static Dictionary<String, SeverityLevel> mCategorySeverityFilters = new Dictionary<string, SeverityLevel>();
        private static SeverityLevel mFallbackSeverityFilter;

        /// <summary>
        /// Gets or sets the filter to use while filtering logging requiests over categories were not explicitly assigned with severity.
        /// </summary>
        /// <example>
        /// The following example shows how to initialize logging with default structure gathered from configuration and
        /// how to filter out messages with different severities.
        /// <code>
        /// private void MainForm_Load(object sender, EventArgs e)
        /// {
        ///     LogManager.Initialize();
        ///     
        ///     LogManager.FallbackSeverityFilter = SeverityLevel.Information | SeverityLevel.Warning | SeverityLevel.Verbose;
        /// }
        /// </code>
        /// </example>
        public static SeverityLevel FallbackSeverityFilter
        {
            get
            {
                return mFallbackSeverityFilter;
            }
            set
            {
                mFallbackSeverityFilter = value;
            }
        }

        /// <summary>
        /// Gets the filter to use while filtering logging requiests over a given category.
        /// </summary>
        /// <param name="Category">The name of the category which filter is to be get or set.</param>
        /// <exception cref="System.Collections.Generic.KeyNotFoundException">There is no such category defined.</exception>
        /// <exception cref="System.ArgumentNullException">Category parameter was null.</exception>
        /// <example>
        /// The following example shows how to initialize logging with default structure gathered from configuration and
        /// how to filter out messages with different severities.
        /// <code>
        /// private void MainForm_Load(object sender, EventArgs e)
        /// {
        ///     LogManager.Initialize();
        ///     
        ///     // Gets severity filter for "NetworkListeners" category - now it is the same as the one
        ///     // loaded from configuration by the call to Initialize above
        ///     SeverityLevel severitylevel = LogManager.GetCategorySeverityFilter("NetworkListeners");
        /// }
        /// </code>
        /// </example>
        public static SeverityLevel GetCategorySeverityFilter(String Category)
        {
            lock (mCategorySeverityFilters)
            {
                return mCategorySeverityFilters[Category];
            }
        }

        /// <summary>
        /// Sets the filter to use while filtering logging requiests over a given category.
        /// </summary>
        /// <param name="Category">The name of the category which filter is to be get or set.</param>
		/// <param name="SeverityFilter">SeverityLevel of category</param>
        /// <exception cref="System.ArgumentNullException">Category parameter was null.</exception>
        /// <example>
        /// The following example shows how to initialize logging with default structure gathered from configuration and
        /// how to filter out messages with different severities.
        /// <code>
        /// private void MainForm_Load(object sender, EventArgs e)
        /// {
        ///     LogManager.Initialize();
        ///     
        ///     // Only messages with Critical and Error severity will be written through "NetworkListeners" category
        ///     LogManager.SetCategorySeverityFilter("NetworkListeners", SeverityLevel.Information | SeverityLevel.Warning | SeverityLevel.Verbose);
        /// }
        /// </code>
        /// </example>
        public static void SetCategorySeverityFilter(String Category, SeverityLevel SeverityFilter)
        {
            lock (mCategorySeverityFilters)
            {
                mCategorySeverityFilters[Category] = SeverityFilter;
            }
        }
    }
}
